package com.asa.voice.mp3.asa.decoder;

public final class Layer2 extends Layer123 {
	  private Header header;
	  
	  private BitStream bs;
	  
	  private int channels;
	  
	  private int aidx;
	  
	  private int sblimit;
	  
	  private byte[][][] aidx_table;
	  
	  private byte[][] allocation;
	  
	  private byte[][] nbal;
	  
	  private byte[][] sbquant_offset;
	  
	  private byte[][] scfsi;
	  
	  private byte[][][] scalefactor;
	  
	  private int[] cq_steps;
	  
	  private float[] cq_C;
	  
	  private float[] cq_D;
	  
	  private byte[] cq_bits;
	  
	  private byte[] bitalloc_offset;
	  
	  private byte[][] offset_table;
	  
	  private byte[] group;
	  
	  private int[] samplecode;
	  
	  private float[][][] syin;
	  
	  public static final float[] factor = new float[] { 
	      2.0F, 1.587401F, 1.2599211F, 1.0F, 0.7937005F, 0.62996054F, 0.5F, 0.39685026F, 0.31498027F, 0.25F, 
	      0.19842513F, 0.15749013F, 0.125F, 0.099212565F, 0.07874507F, 0.0625F, 0.049606282F, 0.039372534F, 0.03125F, 0.024803141F, 
	      0.019686267F, 0.015625F, 0.012401571F, 0.009843133F, 0.0078125F, 0.0062007853F, 0.0049215667F, 0.00390625F, 0.0031003926F, 0.0024607833F, 
	      0.001953125F, 0.0015501963F, 0.0012303917F, 9.765625E-4F, 7.7509816E-4F, 6.1519584E-4F, 4.8828125E-4F, 3.8754908E-4F, 3.0759792E-4F, 2.4414062E-4F, 
	      1.9377454E-4F, 1.5379896E-4F, 1.2207031E-4F, 9.688727E-5F, 7.689948E-5F, 6.1035156E-5F, 4.8443635E-5F, 3.844974E-5F, 3.0517578E-5F, 2.4221818E-5F, 
	      1.922487E-5F, 1.5258789E-5F, 1.2110909E-5F, 9.612435E-6F, 7.6293945E-6F, 6.0554544E-6F, 4.8062175E-6F, 3.8146973E-6F, 3.0277272E-6F, 2.4031087E-6F, 
	      1.9073486E-6F, 1.5138636E-6F, 1.2015544E-6F, 0.0F };
	  
	  public Layer2(Header paramHeader, IAudio paramIAudio) {
	    super(paramHeader, paramIAudio);
	    this.header = paramHeader;
	    this.channels = paramHeader.getChannels();
	    this.bs = new BitStream(4096, 512);
	    this.nbal = new byte[5][];
	    (new byte[27])[0] = 4;
	    (new byte[27])[1] = 4;
	    (new byte[27])[2] = 4;
	    (new byte[27])[3] = 4;
	    (new byte[27])[4] = 4;
	    (new byte[27])[5] = 4;
	    (new byte[27])[6] = 4;
	    (new byte[27])[7] = 4;
	    (new byte[27])[8] = 4;
	    (new byte[27])[9] = 4;
	    (new byte[27])[10] = 4;
	    (new byte[27])[11] = 3;
	    (new byte[27])[12] = 3;
	    (new byte[27])[13] = 3;
	    (new byte[27])[14] = 3;
	    (new byte[27])[15] = 3;
	    (new byte[27])[16] = 3;
	    (new byte[27])[17] = 3;
	    (new byte[27])[18] = 3;
	    (new byte[27])[19] = 3;
	    (new byte[27])[20] = 3;
	    (new byte[27])[21] = 3;
	    (new byte[27])[22] = 3;
	    (new byte[27])[23] = 2;
	    (new byte[27])[24] = 2;
	    (new byte[27])[25] = 2;
	    (new byte[27])[26] = 2;
	    this.nbal[0] = new byte[27];
	    (new byte[30])[0] = 4;
	    (new byte[30])[1] = 4;
	    (new byte[30])[2] = 4;
	    (new byte[30])[3] = 4;
	    (new byte[30])[4] = 4;
	    (new byte[30])[5] = 4;
	    (new byte[30])[6] = 4;
	    (new byte[30])[7] = 4;
	    (new byte[30])[8] = 4;
	    (new byte[30])[9] = 4;
	    (new byte[30])[10] = 4;
	    (new byte[30])[11] = 3;
	    (new byte[30])[12] = 3;
	    (new byte[30])[13] = 3;
	    (new byte[30])[14] = 3;
	    (new byte[30])[15] = 3;
	    (new byte[30])[16] = 3;
	    (new byte[30])[17] = 3;
	    (new byte[30])[18] = 3;
	    (new byte[30])[19] = 3;
	    (new byte[30])[20] = 3;
	    (new byte[30])[21] = 3;
	    (new byte[30])[22] = 3;
	    (new byte[30])[23] = 2;
	    (new byte[30])[24] = 2;
	    (new byte[30])[25] = 2;
	    (new byte[30])[26] = 2;
	    (new byte[30])[27] = 2;
	    (new byte[30])[28] = 2;
	    (new byte[30])[29] = 2;
	    this.nbal[1] = new byte[30];
	    (new byte[8])[0] = 4;
	    (new byte[8])[1] = 4;
	    (new byte[8])[2] = 3;
	    (new byte[8])[3] = 3;
	    (new byte[8])[4] = 3;
	    (new byte[8])[5] = 3;
	    (new byte[8])[6] = 3;
	    (new byte[8])[7] = 3;
	    this.nbal[2] = new byte[8];
	    (new byte[12])[0] = 4;
	    (new byte[12])[1] = 4;
	    (new byte[12])[2] = 3;
	    (new byte[12])[3] = 3;
	    (new byte[12])[4] = 3;
	    (new byte[12])[5] = 3;
	    (new byte[12])[6] = 3;
	    (new byte[12])[7] = 3;
	    (new byte[12])[8] = 3;
	    (new byte[12])[9] = 3;
	    (new byte[12])[10] = 3;
	    (new byte[12])[11] = 3;
	    this.nbal[3] = new byte[12];
	    (new byte[30])[0] = 4;
	    (new byte[30])[1] = 4;
	    (new byte[30])[2] = 4;
	    (new byte[30])[3] = 4;
	    (new byte[30])[4] = 3;
	    (new byte[30])[5] = 3;
	    (new byte[30])[6] = 3;
	    (new byte[30])[7] = 3;
	    (new byte[30])[8] = 3;
	    (new byte[30])[9] = 3;
	    (new byte[30])[10] = 3;
	    (new byte[30])[11] = 2;
	    (new byte[30])[12] = 2;
	    (new byte[30])[13] = 2;
	    (new byte[30])[14] = 2;
	    (new byte[30])[15] = 2;
	    (new byte[30])[16] = 2;
	    (new byte[30])[17] = 2;
	    (new byte[30])[18] = 2;
	    (new byte[30])[19] = 2;
	    (new byte[30])[20] = 2;
	    (new byte[30])[21] = 2;
	    (new byte[30])[22] = 2;
	    (new byte[30])[23] = 2;
	    (new byte[30])[24] = 2;
	    (new byte[30])[25] = 2;
	    (new byte[30])[26] = 2;
	    (new byte[30])[27] = 2;
	    (new byte[30])[28] = 2;
	    (new byte[30])[29] = 2;
	    this.nbal[4] = new byte[30];
	    this.aidx_table = new byte[][][] { { { 
	            0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 
	            1, 1, 1, 1, 1, 0 }, { 
	            0, 2, 2, 0, 0, 0, 1, 1, 1, 1, 
	            1, 1, 1, 1, 1, 0 } }, { { 
	            0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 
	            0, 0, 0, 0, 0, 0 }, { 
	            0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 
	            0, 0, 0, 0, 0, 0 } }, { { 
	            0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 
	            1, 1, 1, 1, 1, 0 }, { 
	            0, 3, 3, 0, 0, 0, 1, 1, 1, 1, 
	            1, 1, 1, 1, 1, 0 } } };
	    this.cq_steps = new int[] { 
	        3, 5, 7, 9, 15, 31, 63, 127, 255, 511, 
	        1023, 2047, 4095, 8191, 16383, 32767, 65535 };
	    this.cq_C = new float[] { 
	        1.3333333F, 1.6F, 1.1428571F, 1.7777778F, 1.0666667F, 1.0322582F, 1.015873F, 1.007874F, 1.0039216F, 1.0019569F, 
	        1.0009775F, 1.0004885F, 1.0002441F, 1.000122F, 1.000061F, 1.0000305F, 1.0000153F };
	    this.cq_D = new float[] { 
	        0.5F, 0.5F, 0.25F, 0.5F, 0.125F, 0.0625F, 0.03125F, 0.015625F, 0.0078125F, 0.00390625F, 
	        0.001953125F, 9.765625E-4F, 4.8828125E-4F, 2.4414062E-4F, 1.2207031E-4F, 6.103516E-5F, 3.051758E-5F };
	    this.cq_bits = new byte[] { 
	        5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 
	        10, 11, 12, 13, 14, 15, 16 };
	    this.sbquant_offset = new byte[][] { { 
	          7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 
	          6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
	          3, 3, 3, 0, 0, 0, 0 }, { 
	          7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 
	          6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
	          3, 3, 3, 0, 0, 0, 0, 0, 0, 0 }, { 5, 5, 2, 2, 2, 2, 2, 2 }, { 
	          5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 
	          2, 2 }, { 
	          4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 
	          2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
	          1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
	    this.bitalloc_offset = new byte[] { 0, 3, 3, 1, 2, 3, 4, 5 };
	    this.offset_table = new byte[][] { { 0, 1, 16 }, { 0, 1, 2, 3, 4, 5, 16 }, { 
	          0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
	          10, 11, 12, 13, 14 }, { 
	          0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 
	          11, 12, 13, 14, 15 }, { 
	          0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
	          10, 11, 12, 13, 16 }, { 
	          0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 
	          12, 13, 14, 15, 16 } };
	    this.group = new byte[] { 
	        2, 3, 0, 4, 0, 0, 0, 0, 0, 0, 
	        0, 0, 0, 0, 0, 0, 0 };
	    this.allocation = new byte[2][32];
	    this.scfsi = new byte[2][32];
	    this.scalefactor = new byte[2][32][3];
	    this.samplecode = new int[3];
	    this.syin = new float[2][3][32];
	    if (this.header.getVersion() == 2) {
	      this.aidx = 4;
	      this.sblimit = 30;
	    } else {
	      this.aidx = this.aidx_table[this.header.getSamplingFrequency()][2 - this.channels][this.header.getBitrateIndex()];
	      if (this.aidx == 0) {
	        this.sblimit = 27;
	      } else if (this.aidx == 1) {
	        this.sblimit = 30;
	      } else if (this.aidx == 2) {
	        this.sblimit = 8;
	      } else {
	        this.sblimit = 12;
	      } 
	    } 
	  }
	  
	  private void requantization(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
	    int i = this.cq_steps[paramInt1];
	    byte b;
	    if ((b = this.group[paramInt1]) != 0) {
	      int j = this.bs.getBits17(this.cq_bits[paramInt1]);
	      for (byte b2 = 0; b2 < 3; b2++) {
	        this.samplecode[b2] = j % i;
	        j /= i;
	      } 
	      i = (1 << b) - 1;
	    } else {
	      b = this.cq_bits[paramInt1];
	      for (byte b2 = 0; b2 < 3; b2++)
	        this.samplecode[b2] = this.bs.getBits17(b); 
	    } 
	    for (byte b1 = 0; b1 < 3; b1++) {
	      float f = 2.0F * this.samplecode[b1] / (i + 1) - 1.0F;
	      this.syin[paramInt3][b1][paramInt4] = this.cq_C[paramInt1] * (f + this.cq_D[paramInt1]);
	      this.syin[paramInt3][b1][paramInt4] = this.syin[paramInt3][b1][paramInt4] * factor[this.scalefactor[paramInt3][paramInt4][paramInt2 >> 2]];
	    } 
	  }
	  
	  private void stereo(int paramInt1, int paramInt2, int paramInt3) {
	    int i = this.cq_steps[paramInt1];
	    byte b;
	    if ((b = this.group[paramInt1]) != 0) {
	      int j = this.bs.getBits17(this.cq_bits[paramInt1]);
	      for (byte b2 = 0; b2 < 3; b2++) {
	        this.samplecode[b2] = j % i;
	        j /= i;
	      } 
	      i = (1 << b) - 1;
	    } else {
	      b = this.cq_bits[paramInt1];
	      for (byte b2 = 0; b2 < 3; b2++)
	        this.samplecode[b2] = this.bs.getBits17(b); 
	    } 
	    for (byte b1 = 0; b1 < 3; b1++) {
	      float f = 2.0F * this.samplecode[b1] / (i + 1) - 1.0F;
	      this.syin[1][b1][paramInt3] = this.cq_C[paramInt1] * (f + this.cq_D[paramInt1]);
	      this.syin[0][b1][paramInt3] = this.cq_C[paramInt1] * (f + this.cq_D[paramInt1]);
	      this.syin[0][b1][paramInt3] = this.syin[0][b1][paramInt3] * factor[this.scalefactor[0][paramInt3][paramInt2 >> 2]];
	      this.syin[1][b1][paramInt3] = this.syin[1][b1][paramInt3] * factor[this.scalefactor[1][paramInt3][paramInt2 >> 2]];
	    } 
	  }
	  
	  public int decodeFrame(byte[] paramArrayOfbyte, int paramInt) {
	    int m = this.header.getMainDataSize();
	    if (this.bs.append(paramArrayOfbyte, paramInt, m) < m)
	      return paramInt + m; 
	    paramInt += m;
	    int i = this.bs.getBytePos();
	    int j = (this.header.getMode() == 1) ? (this.header.getModeExtension() + 1 << 2) : 32;
	    if (j > this.sblimit)
	      j = this.sblimit; 
	    int k;
	    for (k = 0; k < j; k++) {
	      for (byte b1 = 0; b1 < this.channels; b1++)
	        this.allocation[b1][k] = (byte)this.bs.getBits9(this.nbal[this.aidx][k]); 
	    } 
	    for (k = j; k < this.sblimit; k++) {
	      this.allocation[0][k] = (byte)this.bs.getBits9(this.nbal[this.aidx][k]);
	      this.allocation[1][k] = (byte)this.bs.getBits9(this.nbal[this.aidx][k]);
	    } 
	    for (k = 0; k < this.sblimit; k++) {
	      for (byte b1 = 0; b1 < this.channels; b1++) {
	        if (this.allocation[b1][k] != 0) {
	          this.scfsi[b1][k] = (byte)this.bs.getBits9(2);
	        } else {
	          this.scfsi[b1][k] = 0;
	        } 
	      } 
	    } 
	    for (k = 0; k < this.sblimit; k++) {
	      for (byte b1 = 0; b1 < this.channels; b1++) {
	        if (this.allocation[b1][k] != 0) {
	          this.scalefactor[b1][k][0] = (byte)this.bs.getBits9(6);
	          switch (this.scfsi[b1][k]) {
	            case 2:
	              this.scalefactor[b1][k][1] = this.scalefactor[b1][k][0];
	              this.scalefactor[b1][k][2] = this.scalefactor[b1][k][0];
	              break;
	            case 0:
	              this.scalefactor[b1][k][1] = (byte)this.bs.getBits9(6);
	            case 1:
	            case 3:
	              this.scalefactor[b1][k][2] = (byte)this.bs.getBits9(6);
	              break;
	          } 
	          if ((this.scfsi[b1][k] & 0x1) == 1)
	            this.scalefactor[b1][k][1] = this.scalefactor[b1][k][this.scfsi[b1][k] - 1]; 
	        } 
	      } 
	    } 
	    for (byte b = 0; b < 12; b++) {
	      for (k = 0; k < j; k++) {
	        for (byte b2 = 0; b2 < this.channels; b2++) {
	          byte b3;
	          if ((b3 = this.allocation[b2][k]) != 0) {
	            b3 = this.offset_table[this.bitalloc_offset[this.sbquant_offset[this.aidx][k]]][b3 - 1];
	            requantization(b3, b, b2, k);
	          } else {
	            this.syin[b2][2][k] = 0.0F;
	            this.syin[b2][1][k] = 0.0F;
	            this.syin[b2][0][k] = 0.0F;
	          } 
	        } 
	      } 
	      for (k = j; k < this.sblimit; k++) {
	        byte b2;
	        if ((b2 = this.allocation[0][k]) != 0) {
	          b2 = this.offset_table[this.bitalloc_offset[this.sbquant_offset[this.aidx][k]]][b2 - 1];
	          stereo(b2, b, k);
	        } else {
	          for (byte b3 = 0; b3 < this.channels; b3++) {
	            this.syin[b3][2][k] = 0.0F;
	            this.syin[b3][1][k] = 0.0F;
	            this.syin[b3][0][k] = 0.0F;
	          } 
	        } 
	      } 
	      byte b1;
	      for (b1 = 0; b1 < this.channels; b1++) {
	        for (byte b2 = 0; b2 < 3; b2++) {
	          for (k = this.sblimit; k < 32; k++)
	            this.syin[b1][b2][k] = 0.0F; 
	        } 
	      } 
	      for (b1 = 0; b1 < this.channels; b1++) {
	        for (byte b2 = 0; b2 < 3; b2++)
	          this.filter.synthesisSubBand(this.syin[b1][b2], b1); 
	      } 
	    } 
	    int n = m + i - this.bs.getBytePos();
	    this.bs.skipBytes(n);
	    outputAudio();
	    return paramInt;
	  }
	}
